package xyz.lisys.groovy

// http://groovy-lang.org/documentation.html

void readGitHelp() {
    def process = Runtime.getRuntime().exec('git help')
    def reader = new BufferedReader(new InputStreamReader(process.getInputStream()))
    String line
    while ((line = reader.readLine()) != null) {
        println line
    }
}

void gReadGitHelp() {
    println 'git help'.execute().text
}

def foo(Closure callback) {
    callback()
    callback.call()
    println 'world'
}

def name(String c) {
    println c
}

class Person {
    String name
    Integer age
}

static def person(Closure callback) {
    def p = new Person()
    callback.delegate = p

    // 本文详细探讨了闭包在Groovy和Java中的代理策略，
    // 包括OWNER_FIRST、DELEGATE_FIRST、OWNER_ONLY和DELEGATE_ONLY四种情况，揭示了如何影响方法查找和执行
    // OWNER_FIRST : 所有者中的方法优先 ;
    // DELEGATE_FIRST : 代理优先策略 , 代理中的方法优先 ;
    // OWNER_ONLY : 只执行所有者中的方法 ;
    // DELEGATE_ONLY : 只执行代理中的方法 ;
    // TO_SELF : 只在自身查找 ;
    // callback.resolveStrategy = Closure.DELEGATE_FIRST

    callback()
    return p
}

foo {
    // 包含隐式参数it
    println 'hello'
    name 'hello'

    getThisObject().name 'hello'

    // this 对应于定义闭包的封闭类
    // owner 对应于定义闭包的封闭对象，该对象可以是类或闭包，定义到闭包时是闭包对象
    // delegate 同owner可以被修改
    this.name 'hello'
    owner.name 'hello'
    delegate.name 'hello'
}

class Free {
    Free() {
    }

    void call() {
        go({
            say '111'
        })
    }

    void go(callback) {
        callback.call()
    }

    public say(name) {
        println name
    }
}

new Free().call()

// 字符串模板
def number = 1
def eagerGString = "value == ${number}"
def lazyGString = "value == ${-> number}"

println eagerGString
println lazyGString

number = 2

println eagerGString
println lazyGString

// List
def heterogeneous = [1, 'a', true]
def letters = [1, 2, 3, 4, 5]
letters << 6
letters.forEach { println it }
println letters[1, 3]
println letters[1..3]

// Map
def colors = [red: '#FF0000', green: '#00FF00', blue: '#0000FF']
println colors['red']
println colors.green

// 运算符
def person = new Person(age: 5)
println person.age <=> 3

// 安全占位符
println person.name?.charAt(1)

// 直接域访问符
println person.@age

// 方法指针操作符
letters.&forEach

def persons = [
        new Person(name: 'a', age: 1),
        new Person(name: 'b', age: 2),
        new Person(name: 'c', age: 3)
]
// 展开执行操作符
persons*.setAge(20)
persons.forEach { println it.getAge() }


